/**
 * Created by XHL on 2022-07-27.
 */

#include <GameObject.h>

namespace entity {
	GameObject::GameObject(const handle::PInfo &info) : m_info(info) {
		this->m_info.location += global::left_top;
	}

	/**
	 * this method will modify its own direction and location
	 * @param direction direction
	 * @param step move stride
	 * @return true if moved or false else
	 */
	bool GameObject::move(const Direction &direction, const int &step) {
		meta::Location previous_location = this->m_info.location;
		meta::Location delta[] = {
				{ 0,                   -1 },
				{ 0,                   1 },
				{ -this->m_info.width, 0 },
				{ this->m_info.width,  0 }
		};
		/** trying to update the Location */
		this->m_info.location += delta[direction];
		/** If location not changed, return false */
		Location &new_location = this->m_info.location;
		if (new_location == previous_location) return false;
		/** If location changed, update direction and re-draw itself */
		this->set_direction(direction);
		this->erase_self(previous_location);
		this->display_self(new_location);
		return true;
	}

	void GameObject::erase_self(const meta::Location &previous_location) const {
		handle::set_cursor_location(previous_location);
		tool::format << "\033[" << this->m_info.width << "X";
		std::cout << tool::format.str();
		tool::format.clear();
	}

	void GameObject::display_self(const Location &new_location) const {
		using namespace global;
		handle::set_cursor_location(this->m_info.location);
		std::cout << this->m_info.color << this->m_info.name << end[this->m_info.direction] << ESC;
	}

	void GameObject::set_direction(const Direction &direction) {
		this->m_info.direction = direction;
	}
} // entity